package com.main;



import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.main.Character.Type;
import com.badlogic.gdx.math.Vector3;

public class Game extends Screen{
	static final int mapCols = 1024;
	static final int mapRows = 1024;
	static final int tileWidth = 64;
	static final int tileHeight = 64;
	SpriteBatch sb;
	OrthographicCamera gameCam;
	OrthographicCamera guiCam;
	Character character;
	NPC_Steve steve;
	Tile[][] map;
	Main main;
	boolean movingLeft;
	boolean movingRight;
	boolean movingUp;
	boolean movingDown;
	boolean action;
	boolean actionComplete;
	int movetimer;
	int animationspeed;
	int animationOrder;
	Vector2[] treeEmitters;
	Vector2[] waterEmitters;
	Array<Animation> animations;
	Array<Animation> charanimations;
	ConversationFrame convFrame;
	Sprite bag;
	int hotkeyUsed;
	Sprite markedTile;
	Rectangle bounds;
	Vector3 tempVec;
	NPC interactingWith;
	boolean interacting;
	int teleportTarget;
	public Game(Main m) {
		teleportTarget = 1;
		tempVec = new Vector3();
		markedTile = new Sprite(new Texture(Gdx.files.internal("data/markedTile.png")));
		bounds = new Rectangle(0,0,10,10);
		hotkeyUsed = 0;
		bag = new Sprite(new Texture(Gdx.files.internal("data/backpack.png")));
		bag.setPosition(Gdx.graphics.getWidth()-bag.getWidth(), 0);
		convFrame = new ConversationFrame();
		treeEmitters = new Vector2[MathUtils.random(2)+4];
		waterEmitters = new Vector2[MathUtils.random(2)+2];
		int loggersForrest = 0;
		treeEmitters[0] = new Vector2(MathUtils.random(5),MathUtils.random(5));
		for (int i = 1; i < treeEmitters.length;i++){
			treeEmitters[i] = new Vector2(MathUtils.random(1024),MathUtils.random(1024));
			System.out.println("Forrest at : " + treeEmitters[i].x + " " + treeEmitters[i].y);
		}
		for (int i = 0; i < waterEmitters.length;i++) {
			waterEmitters[i] = new Vector2(MathUtils.random(1024),MathUtils.random(1024));
			System.out.println("Water at : " + waterEmitters[i].x + " " + waterEmitters[i].y);
		}
		animationOrder = 0;
		animations = new Array<Animation>();
		charanimations = new Array<Animation>();
		action = false;
		actionComplete = false;
		main = m;
		character = new Character(512,512);
		character.setActiveSprite(0);
		character.direction = Character.Direction.South;
		sb = new SpriteBatch();
		gameCam = new OrthographicCamera();
		guiCam = new OrthographicCamera();
		gameCam.position.set(character.xpos*64,character.ypos*64,0);
		guiCam.position.set(Gdx.graphics.getWidth()/2,Gdx.graphics.getHeight()/2,0);
		map = new Tile[mapRows][mapCols];
		for (int j = 0; j <mapRows; j++) {
			for (int i = 0; i < mapCols; i++) {
				if (j == 0 || i == 0 || j == mapRows-1 || i == mapCols-1) {
					map[j][i] = new Tile(StaticTileData.Type.Wall);
				} else {
					map[j][i] = new Tile(StaticTileData.Type.Grass);
				}
			}
		}
		generateInitialTerrain(loggersForrest);
	}
	public void generateInitialTerrain(int steveposx) {
		for (int i = 0; i < treeEmitters.length; i++) {
			float lowerbound = treeEmitters[i].y-20;
			float upperbound = treeEmitters[i].y+20;
			float lowerbound2 = treeEmitters[i].x-20;
			float upperbound2 = treeEmitters[i].x+20;
			lowerbound = MathUtils.clamp(lowerbound, 0, mapRows-1);
			upperbound = MathUtils.clamp(upperbound, 0, mapRows-1);
			lowerbound2 = MathUtils.clamp(lowerbound2, 0, mapCols-1);
			upperbound2 = MathUtils.clamp(upperbound2, 0, mapCols-1);
			for (int j = (int)lowerbound; j <upperbound; j++) {
				for (int k = (int)lowerbound2; k < upperbound2; k++) {
					if ((treeEmitters[i].x-k)*(treeEmitters[i].x-k)+(treeEmitters[i].y-j)*(treeEmitters[i].y-j) <= 20*20) {
						int treeSort = MathUtils.random(100);
						if (treeSort < 15) {
							if (map[j][k].type == StaticTileData.Type.Grass) {
								map[j][k].type = StaticTileData.Type.tree_big_with_apples;
							}
						} else if (treeSort < 30) {
							if (map[j][k].type == StaticTileData.Type.Grass) {
								map[j][k].type = StaticTileData.Type.tree_big;
							}
						} else if (treeSort < 40) {
							if (map[j][k].type == StaticTileData.Type.Grass) {
								map[j][k].type = StaticTileData.Type.tree_medium;
							}
						} else if (treeSort < 50) {
							if (map[j][k].type == StaticTileData.Type.Grass) {
								map[j][k].type = StaticTileData.Type.tree_small;
							}
						}
					}
				}
			}
			if(i == steveposx){
				int ypos = (int)treeEmitters[i].y-20;
				int xpos = (int)treeEmitters[i].x-3;
				if (ypos<0) {
					ypos = (int)treeEmitters[i].y+20;
				}
				if (xpos-3<0) {
					xpos = (int)treeEmitters[i].y+3;
				}
				steve = new NPC_Steve(xpos,ypos);

				steve.setActiveSprite(StaticTextures.lumberman2axe);
				map[steve.ypos][steve.xpos].type = StaticTileData.Type.Grass;
				System.out.println((xpos) + "," +(ypos));
			}

		}
		for (int i = 0; i < waterEmitters.length; i++) {
			float lowerbound = waterEmitters[i].y-4;
			float upperbound = waterEmitters[i].y+4;
			float lowerbound2 = waterEmitters[i].x-4;
			float upperbound2 = waterEmitters[i].x+4;
			lowerbound = MathUtils.clamp(lowerbound, 0, mapRows-1);
			upperbound = MathUtils.clamp(upperbound, 0, mapRows-1);
			lowerbound2 = MathUtils.clamp(lowerbound2, 0, mapCols-1);
			upperbound2 = MathUtils.clamp(upperbound2, 0, mapCols-1);
			for (int j = (int)lowerbound; j <upperbound; j++) {
				for (int k = (int)lowerbound2; k < upperbound2; k++) {
					if ((waterEmitters[i].x-k)*(waterEmitters[i].x-k)+(waterEmitters[i].y-j)*(waterEmitters[i].y-j) <= 4*4) {
						map[j][k].type = StaticTileData.Type.Water_Deep;
						waterAroundDeep(k,j,100);
					}
				}
			}
		}
	}
	public void waterAroundDeep(int x, int y, int percentToSpread) {
		int dxLower = -1;
		int dxUpper = 1;
		int dyLower = -1;
		int dyUpper = 1;
		if (x == 0)
			dxLower = 0;
		if (x == 1023)
			dxUpper = 0;
		if (y == 0)
			dyLower = 0;
		if (y == 1023)
			dyUpper = 0;
		for (int dx = dxLower; dx <= dxUpper; dx++) {
			for (int dy = dyLower; dy <= dyUpper; dy++) {
				if (MathUtils.random(100) < percentToSpread) {
					if (!(map[y+dy][x+dx].type == StaticTileData.Type.Water_Deep)) {
						map[y+dy][x+dx].type = StaticTileData.Type.Water;
						this.calculateSpriteWater(y+dy, x+dx);
						this.calculateSpriteWaterAround(y+dy, x+dx);
						waterAround(x+dx,y+dy,50);
					}
				}
			}
		}
	}

	public void waterAround(int x, int y, int percentToSpread) {
		if (x < 1023) {
			if (!(map[y][x+1].type == StaticTileData.Type.Water_Deep)) {
				if (MathUtils.random(100) < percentToSpread) {
					map[y][x+1].type = StaticTileData.Type.Water;
					calculateSpriteWater(y,x+1);
					calculateSpriteWaterAround(y,x+1);
					waterAround(x+1,y,percentToSpread-5);
				}
			}
		}
		if (x > 0) {
			if (!(map[y][x-1].type == StaticTileData.Type.Water_Deep)) {
				if (MathUtils.random(100) < percentToSpread) {
					map[y][x-1].type = StaticTileData.Type.Water;
					calculateSpriteWater(y,x-1);
					calculateSpriteWaterAround(y,x-1);
					waterAround(x-1,y,percentToSpread-5);
				}
			}
		}
		if (y < 1023) {
			if (!(map[y+1][x].type == StaticTileData.Type.Water_Deep)) {
				if (MathUtils.random(100) < percentToSpread) {
					map[y+1][x].type = StaticTileData.Type.Water;
					calculateSpriteWater(y+1,x);
					calculateSpriteWaterAround(y+1,x);
					waterAround(x,y+1,percentToSpread-5);
				}
			}
		}
		if (y > 0) {
			if (!(map[y-1][x].type == StaticTileData.Type.Water_Deep)) {
				if (MathUtils.random(100) < percentToSpread) {
					map[y-1][x].type = StaticTileData.Type.Water;
					calculateSpriteWater(y-1,x);
					calculateSpriteWaterAround(y-1,x);
					waterAround(x,y-1,percentToSpread-5);
				}
			}
		}
	}
	public boolean isNearTile(int x, int y, StaticTileData.Type typeToCheckFor) {
		if (map[y][x+1].type == typeToCheckFor) {
			return true;
		}
		if (map[y][x-1].type == typeToCheckFor) {
			return true;
		}
		if (map[y+1][x].type == typeToCheckFor) {
			return true;
		}
		if (map[y-1][x].type == typeToCheckFor) {
			return true;
		}
		return false;
	}
	public void spreadTileToCloseTilesOfType(int x, int y,StaticTileData.Type typeToSpread, StaticTileData.Type target) {
		if (map[y][x+1].type == target) {
			map[y][x+1].type = typeToSpread;
			if (typeToSpread == StaticTileData.Type.Water) {
				this.calculateSpriteWater(y,x+1);
				this.calculateSpriteWaterAround(y, x+1);
			}
			spreadTileToCloseTilesOfType(x+1,y,typeToSpread,target);
		}
		if (map[y][x-1].type == target) {
			map[y][x-1].type = typeToSpread;
			spreadTileToCloseTilesOfType(x-1,y,typeToSpread,target);
			if (typeToSpread == StaticTileData.Type.Water) {
				this.calculateSpriteWater(y,x-1);
				this.calculateSpriteWaterAround(y, x-1);
			}
		}
		if (map[y+1][x].type == target) {
			map[y+1][x].type = typeToSpread;
			spreadTileToCloseTilesOfType(x,y+1,typeToSpread,target);
			if (typeToSpread == StaticTileData.Type.Water) {
				this.calculateSpriteWater(y+1,x);
				this.calculateSpriteWaterAround(y+1, x);
			}
		}
		if (map[y-1][x].type == target) {
			map[y-1][x].type = typeToSpread;
			spreadTileToCloseTilesOfType(x,y-1,typeToSpread,target);
			if (typeToSpread == StaticTileData.Type.Water) {
				this.calculateSpriteWater(y-1,x);
				this.calculateSpriteWaterAround(y-1, x);
			}
		}
	}
	public void calculateSpriteWater(int y, int x) {
		int calcValue = 0;

		try {
			if (map[y+1][x-1].type == StaticTileData.Type.Water || map[y+1][x-1].type == StaticTileData.Type.Water_Deep) {
				calcValue+=1;
			}
		} catch (ArrayIndexOutOfBoundsException e ) {
			calcValue+=1;
		}

		try {
			if (map[y+1][x].type == StaticTileData.Type.Water || map[y+1][x].type == StaticTileData.Type.Water_Deep) {
				calcValue+=2;
			}
		} catch (ArrayIndexOutOfBoundsException e ) {
			calcValue+=2;
		}

		try {
			if (map[y+1][x+1].type == StaticTileData.Type.Water || map[y+1][x+1].type == StaticTileData.Type.Water_Deep) {
				calcValue+=4;
			}
		} catch (ArrayIndexOutOfBoundsException e ) {
			calcValue+=4;
		}

		try {
			if (map[y][x-1].type == StaticTileData.Type.Water || map[y][x-1].type == StaticTileData.Type.Water_Deep) {
				calcValue+=8;
			}
		} catch (ArrayIndexOutOfBoundsException e ) {
			calcValue+=8;
		}

		try {
			if (map[y][x+1].type == StaticTileData.Type.Water || map[y][x+1].type == StaticTileData.Type.Water_Deep) {
				calcValue+=16;
			}
		} catch (ArrayIndexOutOfBoundsException e ) {
			calcValue+=16;
		}

		try {
			if (map[y-1][x-1].type == StaticTileData.Type.Water || map[y-1][x-1].type == StaticTileData.Type.Water_Deep) {
				calcValue+=32;
			}
		} catch (ArrayIndexOutOfBoundsException e ) {
			calcValue+=32;
		}

		try {
			if (map[y-1][x].type == StaticTileData.Type.Water || map[y-1][x].type == StaticTileData.Type.Water_Deep) {
				calcValue+=64;
			}
		} catch (ArrayIndexOutOfBoundsException e ) {
			calcValue+=64;
		}
		try {
			if (map[y-1][x+1].type == StaticTileData.Type.Water || map[y-1][x+1].type == StaticTileData.Type.Water_Deep) {
				calcValue+=128;
			}
		} catch (ArrayIndexOutOfBoundsException e ) {
			calcValue+=128;
		}
		map[y][x].value = calcValue;
	}
	public void calculateSpriteWaterAround(int y, int x) {
		if (y < 1023) {
			if (x > 0)
				calculateSpriteWater(y+1,x-1);
			calculateSpriteWater(y+1,x);
			if (x < 1023)
				calculateSpriteWater(y+1,x+1);
		}
		if (x > 0)
			calculateSpriteWater(y,x-1);
		if (x < 1023)
			calculateSpriteWater(y,x+1);
		if (y > 0) {
			if (x > 0)
				calculateSpriteWater(y-1,x-1);
			calculateSpriteWater(y-1,x);
			if (x < 1023)
				calculateSpriteWater(y-1,x+1);
		}
	}
	public void update() {
		for(int i= animations.size-1; i >=0; i--){
			animations.get(i).setNextSprite();
			if(!animations.get(i).alive)
				animations.removeIndex(i);
		}	
		for(int i= charanimations.size-1; i >=0; i--){
			charanimations.get(i).setNextSprite();
			if(!charanimations.get(i).alive)
				charanimations.removeIndex(i);
		}	
		if (animationspeed > (500/(character.sprites.get(character.type).length)*2)){


			if (animationOrder == (character.sprites.get(character.type).length-1)){
				animationOrder = 0;
				if(action){
					actionComplete = true;
				}
			}
			character.setActiveSprite(animationOrder);
			animationOrder++;
			if(action && actionComplete){
				action = false;
				actionComplete = false;
				character.still(character.direction);
				animationOrder=0;
			}

			animationspeed = 0;
		}

		else{
			animationspeed += Gdx.graphics.getDeltaTime()*1000;
		}


		if (movetimer > 100 && !action) {
			if (movingLeft && !movingRight && !movingUp && !movingDown) {
				moveLeft();
			} else if (!movingLeft && movingRight && !movingUp && !movingDown) {
				moveRight();
			} else if (!movingLeft && !movingRight && movingUp && !movingDown) {
				moveUp();
			} else if (!movingLeft && !movingRight && !movingUp && movingDown) {
				moveDown();
			}
			else{
				if(!action)
					character.type = Character.Type.Stay;
				animationOrder = 0;
			}
			movetimer -= 100;
		} else if(!action){
			movetimer += Gdx.graphics.getDeltaTime()*1000;	
		}


		if(character.type == Type.Down){
			int blinki = MathUtils.random(25);
			if ( blinki == 0){
				charanimations.add(new Animation(character.xpos,character.ypos,StaticTextures.blink,3,50));
			}

		}
		for(Animation e : charanimations){
			e.updatePos(character.xpos, character.ypos);
		}

		gameCam.viewportHeight = Gdx.graphics.getHeight();
		gameCam.viewportWidth = Gdx.graphics.getWidth();
		guiCam.viewportHeight = Gdx.graphics.getHeight();
		guiCam.viewportWidth = Gdx.graphics.getWidth();
		GL10 gl = Gdx.graphics.getGL10();
		gl.glViewport(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
		gameCam.update();
		gameCam.apply(gl);
		guiCam.update();
		guiCam.apply(gl);

	}

	public void render() {
		sb.setProjectionMatrix(gameCam.combined);
		sb.begin();
		int lowerbound = character.ypos-15;
		int upperbound = character.ypos+15;
		int lowerbound2 = character.xpos-15;
		int upperbound2 = character.xpos+15;
		lowerbound = MathUtils.clamp(lowerbound, 0, mapRows-1);
		upperbound = MathUtils.clamp(upperbound, 0, mapRows-1);
		lowerbound2 = MathUtils.clamp(lowerbound2, 0, mapCols-1);
		upperbound2 = MathUtils.clamp(upperbound2, 0, mapCols-1);

		for (int j = upperbound; j > lowerbound; j--) {
			for (int i = lowerbound2; i < upperbound2; i++) {
				map[j][i].render(i*tileWidth, j*tileHeight, sb);
			}
			if (j == character.ypos){
				for(Animation e : animations){
					e.render(sb);
				}
				character.render(sb);
				if (character.xpos > 0) {
					if (character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Hand  ||
							character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Shovel ||
							character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Axe) {
						markedTile.setPosition((character.xpos-1)*tileWidth,character.ypos*tileHeight);
						markedTile.draw(sb);
					}
				} 
				if (character.xpos < 1023) {
					if (character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Hand  ||
							character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Shovel ||
							character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Axe) {
						markedTile.setPosition((character.xpos+1)*tileWidth,character.ypos*tileHeight);
						markedTile.draw(sb);
					}
				}

			}else if (j == character.ypos-1) {
				if (character.ypos > 0) {
					if (character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Hand  ||
							character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Shovel ||
							character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Axe) {
						markedTile.setPosition(character.xpos*tileWidth,(character.ypos-1)*tileHeight);
						markedTile.draw(sb);
					}
				}
			} else if (j == character.ypos+1) {
				if (character.ypos < 1023) {
					if (character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Hand  ||
							character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Shovel ||
							character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Axe) {
						markedTile.setPosition(character.xpos*tileWidth,(character.ypos+1)*tileHeight);
						markedTile.draw(sb);
					}
				}
			}
			if(j == steve.ypos)
				steve.render(sb);
		}


		sb.end();
		sb.setProjectionMatrix(guiCam.combined);
		sb.begin();
		if (!character.inventory.open)
			bag.draw(sb);
		else
			character.inventory.render(sb);
		character.renderActionbar(sb);
		if (convFrame.visible)
			convFrame.render(sb);


		sb.end();
	}

	public void enter() {
		Gdx.input.setInputProcessor(this);
	}
	public void usedTile(int x, int y, int hotKey) {
		if (character.hotKeys.get(hotKey) == StaticInventoryData.GameObject.Hand) {
			System.out.println(x + " " + y + " " + steve.xpos + " " + steve.ypos);
			if (steve.xpos == x && steve.ypos == y) {
				steve.interact(this);
				interacting = true;
				interactingWith = steve;
			} else if (map[y][x].type == StaticTileData.Type.Grass_Blue_Flower_2) {
				if (character.inventory.addObject(StaticInventoryData.GameObject.Flower_Blue,2)) {
					map[y][x].type = StaticTileData.Type.Grass;	
				}
			} else if (map[y][x].type == StaticTileData.Type.Grass_Red_Flower_3) {
				if (character.inventory.addObject(StaticInventoryData.GameObject.Flower_Red,3)) {
					map[y][x].type = StaticTileData.Type.Grass;	
				}
			} else if (map[y][x].type == StaticTileData.Type.BlueBerry) {
				if (character.inventory.addObject(StaticInventoryData.GameObject.BlueBerry,1)){
					map[y][x].type = StaticTileData.Type.Grass;	
				}
			} else if (map[y][x].type == StaticTileData.Type.tree_big_with_apples) {
				map[y][x].type = StaticTileData.Type.tree_big;
				character.inventory.addObject(StaticInventoryData.GameObject.Apple,3);
			}
		} else if (character.hotKeys.get(hotKey) == StaticInventoryData.GameObject.Shovel) {
			if (map[y][x].type == StaticTileData.Type.Grass_Blue_Flower_2) {
				map[y][x].type = StaticTileData.Type.Dirt;
			} else if (map[y][x].type == StaticTileData.Type.Grass_Red_Flower_3) {
				map[y][x].type = StaticTileData.Type.Dirt;
			} else if (map[y][x].type == StaticTileData.Type.Grass) {
				map[y][x].type = StaticTileData.Type.Dirt;
			} else if (map[y][x].type == StaticTileData.Type.BlueBerry) {
				map[y][x].type = StaticTileData.Type.Dirt;
			} else if (map[y][x].type == StaticTileData.Type.Dirt) {
				if (isNearTile(x,y,StaticTileData.Type.Water) || isNearTile(x,y,StaticTileData.Type.Water_Deep)) {
					map[y][x].type = StaticTileData.Type.Water;
					calculateSpriteWater(y,x);
					calculateSpriteWaterAround(y,x);
					spreadTileToCloseTilesOfType(x,y, StaticTileData.Type.Water, StaticTileData.Type.Ditch);
				} else {
					map[y][x].type = StaticTileData.Type.Ditch;
				}
			}
		} else if (character.hotKeys.get(hotKey) == StaticInventoryData.GameObject.Axe) {
			if (character.type == Character.Type.Stay) {
				animationOrder = 0;
				if(character.direction == Character.Direction.East){
					character.type = Character.Type.AxeE;
					animations.add(new Animation(character.xpos+1,character.ypos,StaticTextures.hitting,6,260));
				} else if(character.direction == Character.Direction.West){
					character.type = Character.Type.AxeW;
					animations.add(new Animation(character.xpos-1,character.ypos,StaticTextures.hitting,6,260));
				} else if(character.direction == Character.Direction.North){
					character.type = Character.Type.AxeN;
					animations.add(new Animation(character.xpos,character.ypos+1,StaticTextures.hitting,6,260));
				}
				action = true;
				character.setActiveSprite(animationOrder);
			}
		}
	}
	public void moveLeft() {
		character.type = Character.Type.Left;
		if (map[character.ypos][character.xpos-1].type == StaticTileData.Type.Wall) {
		} else if (map[character.ypos][character.xpos-1].type == StaticTileData.Type.Grass_Stone) {
		} else if (map[character.ypos][character.xpos-1].type == StaticTileData.Type.tree_big) {
		} else if (map[character.ypos][character.xpos-1].type == StaticTileData.Type.tree_big_with_apples) {
		} else if (map[character.ypos][character.xpos-1].type == StaticTileData.Type.tree_medium) {
		} else if (map[character.ypos][character.xpos-1].type == StaticTileData.Type.tree_small) {
		} else if (map[character.ypos][character.xpos-1].type == StaticTileData.Type.Water_Deep) {
		} else if (map[character.ypos][character.xpos-1].type == StaticTileData.Type.Water_Deep) {
		} else {
			character.xpos-=1;	
		}
		if (character.xpos*tileWidth < gameCam.position.x-tileWidth*3) {
			gameCam.position.x -= tileWidth;
		}
	}
	public void moveRight() {
		character.type = Character.Type.Right;
		if (map[character.ypos][character.xpos+1].type == StaticTileData.Type.Wall) {
		} else if (map[character.ypos][character.xpos+1].type == StaticTileData.Type.Grass_Stone) {
		} else if (map[character.ypos][character.xpos+1].type == StaticTileData.Type.tree_big) {
		} else if (map[character.ypos][character.xpos+1].type == StaticTileData.Type.tree_big_with_apples) {
		} else if (map[character.ypos][character.xpos+1].type == StaticTileData.Type.tree_medium) {
		} else if (map[character.ypos][character.xpos+1].type == StaticTileData.Type.tree_small) {
		} else if (map[character.ypos][character.xpos+1].type == StaticTileData.Type.Water_Deep) {
		} else if (map[character.ypos][character.xpos+1].type == StaticTileData.Type.Water_Deep) {
		} else {
			character.xpos+=1;
		}
		if (character.xpos*tileWidth > gameCam.position.x+tileWidth*3) {
			gameCam.position.x += tileWidth;
		}
	}
	public void moveUp() {
		character.type = Character.Type.Up;
		if (map[character.ypos+1][character.xpos].type == StaticTileData.Type.Wall) {
		} else if (map[character.ypos+1][character.xpos].type == StaticTileData.Type.Grass_Stone) {
		} else if (map[character.ypos+1][character.xpos].type == StaticTileData.Type.tree_big) {
		} else if (map[character.ypos+1][character.xpos].type == StaticTileData.Type.tree_big_with_apples) {
		} else if (map[character.ypos+1][character.xpos].type == StaticTileData.Type.tree_medium) {
		} else if (map[character.ypos+1][character.xpos].type == StaticTileData.Type.tree_small) {
		} else if (map[character.ypos+1][character.xpos].type == StaticTileData.Type.Water_Deep) {
		} else {
			character.ypos+=1;
		}
		if (character.ypos*tileHeight > gameCam.position.y+tileHeight*2) {
			gameCam.position.y += tileHeight;
		}
	}
	public void moveDown() {
		character.type = Character.Type.Down;
		if (map[character.ypos-1][character.xpos].type == StaticTileData.Type.Wall) {
		} else if (map[character.ypos-1][character.xpos].type == StaticTileData.Type.Grass_Stone) {
		} else if (map[character.ypos-1][character.xpos].type == StaticTileData.Type.tree_big) {
		} else if (map[character.ypos-1][character.xpos].type == StaticTileData.Type.tree_big_with_apples) {
		} else if (map[character.ypos-1][character.xpos].type == StaticTileData.Type.tree_medium) {
		} else if (map[character.ypos-1][character.xpos].type == StaticTileData.Type.tree_small) {
		} else if (map[character.ypos-1][character.xpos].type == StaticTileData.Type.Water_Deep) {
		} else {
			character.ypos-=1;
		}
		if (character.ypos*tileHeight < gameCam.position.y-tileHeight*2) {
			gameCam.position.y -= tileHeight;
		}
	}

	public boolean keyDown(int key) {
		if (interacting) {
			if (convFrame.currentType == ConversationFrame.DisplayType.Listen) { 
				convFrame.setNext();
			} else if (convFrame.currentType == ConversationFrame.DisplayType.Talk) {
				if (Input.Keys.NUM_1 == key) {
					interactingWith.say(1,this);
				} else if (Input.Keys.NUM_2 == key) {
					interactingWith.say(2,this);
				} else if (Input.Keys.NUM_3 == key) {
					interactingWith.say(3,this);							
				}
			}
			if (!convFrame.visible && interacting) {
				interactingWith.nextInteract(this);
			}
		} else {
			if (Input.Keys.A == key) {
				if (!movingLeft && !action) {
					moveLeft();
					movetimer = 0;
					character.direction =  Character.Direction.West;
				}
				movingLeft = true;
			} else if (Input.Keys.D == key) {
				if (!movingRight && !action) {
					moveRight();
					movetimer = 0;
					character.direction =  Character.Direction.East;
				}
				movingRight = true;
			} else if (Input.Keys.W == key) {
				if (!movingUp && !action) {
					moveUp();
					movetimer = 0;
					character.direction =  Character.Direction.North;
				}
				movingUp = true;
			} else if (Input.Keys.S == key) {
				if (!movingDown && !action) {
					moveDown();
					movetimer = 0;
					character.direction = Character.Direction.South;
				}
				movingDown = true;
			} else if (Input.Keys.SPACE == key) {
				System.out.println(character.xpos + " " + character.ypos);
			} else if (Input.Keys.NUM_1 == key) {
				hotkeyUsed = 1;
			} else if (Input.Keys.NUM_2 == key) {
				hotkeyUsed = 2;
			} else if (Input.Keys.NUM_3 == key) {
				hotkeyUsed = 3;
			} else if (Input.Keys.NUM_4 == key) {
				hotkeyUsed = 4;
			} else if (Input.Keys.NUM_5 == key) {
				hotkeyUsed = 5;
			} else if (Input.Keys.T == key) {
				// Teleport
				if (teleportTarget == 1) {
					int ypos = steve.ypos;
					int xpos = steve.xpos-1;
					if (xpos<0) {
						xpos =  steve.xpos+1;
					}
					character.xpos = xpos;
					character.ypos = ypos;
					teleportTarget = 2;
				} else if (teleportTarget == 2) {
					int ypos = (int)waterEmitters[0].y-10;
					int xpos = (int)waterEmitters[0].x;
					if (ypos<0) {
						ypos = (int)waterEmitters[0].y+10;
					}
					character.xpos = xpos;
					character.ypos = ypos;
					teleportTarget = 1;
				}
				gameCam.position.x = character.xpos*64;
				gameCam.position.y = character.ypos*64;
			}
		}
		return false;
	}
	@Override
	public boolean keyTyped(char arg0) {
		return false;
	}

	@Override
	public boolean keyUp(int key) {
		if(!action){
			if (Input.Keys.A == key) {
				movingLeft = false;
				character.still(character.direction);
			} else if (Input.Keys.D == key) {
				movingRight = false;
				character.still(character.direction);
			} else if (Input.Keys.W == key) {
				movingUp = false;
				character.still(character.direction);
			} else if (Input.Keys.S == key) {
				movingDown = false;
				character.still(character.direction);
			}
		}else{
			movingLeft = false;
			movingRight = false;
			movingUp = false;
			movingDown = false;
		}

		return false;
	}

	public boolean scrolled(int arg0) {
		return false;
	}

	public boolean touchDown(int x, int y, int arg2, int arg3) {
		tempVec.set(x,y,0);
		gameCam.unproject(tempVec);
		y = Gdx.graphics.getHeight()-y;
		if (character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Hand || character.hotKeys.get(hotkeyUsed) == StaticInventoryData.GameObject.Shovel || character.hotKeys.get(hotkeyUsed)==StaticInventoryData.GameObject.Axe) {
			bounds.set(character.xpos*64,character.ypos*64+64,64,64);
			if (bounds.contains(tempVec.x,tempVec.y)) {
				this.usedTile(character.xpos,character.ypos+1,hotkeyUsed);
			}
			bounds.set(character.xpos*64,character.ypos*64-64,64,64);
			if (bounds.contains(tempVec.x,tempVec.y)) {
				this.usedTile(character.xpos,character.ypos-1,hotkeyUsed);
			}
			bounds.set(character.xpos*64+64,character.ypos*64,64,64);
			if (bounds.contains(tempVec.x,tempVec.y)) {
				this.usedTile(character.xpos+1,character.ypos,hotkeyUsed);
			}
			bounds.set(character.xpos*64-64,character.ypos*64,64,64);
			if (bounds.contains(tempVec.x,tempVec.y)) {
				this.usedTile(character.xpos-1,character.ypos,hotkeyUsed);
			}
		}
		hotkeyUsed = 0;
		if (bag.getBoundingRectangle().contains(x,y) && !character.inventory.open) {
			character.inventory.open = true;
		}
		return false;
	}

	public boolean touchDragged(int arg0, int arg1, int arg2) {
		return false;
	}

	public boolean touchMoved(int arg0, int arg1) {
		return false;
	}

	public boolean touchUp(int arg0, int arg1, int arg2, int arg3) {
		return false;
	}


}
